﻿namespace KeRui.Upload
{
    using System;
    using System.IO;
    using System.Text;

    internal class SubStream : Stream
    {
        private long mLength;
        private long mLockPos;
        private long mPosition;
        private long mStart;
        private Stream mStream;

        public SubStream(Stream inStream)
        {
            this.mStream = inStream;
            this.mStart = 0L;
            this.mLength = inStream.Length;
            this.mPosition = 0L;
            this.mLockPos = 0L;
        }

        public SubStream(SubStream inStream, int inStart, int inLength)
        {
            if (inStart < 0)
            {
                inStart = 0;
            }
            if (inLength < 0)
            {
                inLength = 0;
            }
            if (inStart > inStream.Length)
            {
                inStart = (int) inStream.Length;
            }
            if (inLength > (inStream.Length - inStart))
            {
                inLength = ((int) inStream.Length) - inStart;
            }
            this.mStream = inStream.mStream;
            this.mStart = inStart + inStream.mStart;
            this.mLength = inLength;
            this.mPosition = 0L;
        }

        public override void Flush()
        {
            this.mStream.Flush();
        }

        public Stream Lock()
        {
            this.mLockPos = this.mStream.Position;
            this.mStream.Position = this.mStart + this.mPosition;
            return this.mStream;
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            long num = this.mLength - this.mPosition;
            long num2 = this.mStart + this.mPosition;
            this.mPosition += count;
            if (num < count)
            {
                count = (int) num;
            }
            if (count < 0)
            {
                count = 0;
            }
            if (count > 0)
            {
                long position = this.mStream.Position;
                this.mStream.Position = num2;
                count = this.mStream.Read(buffer, offset, count);
                this.mStream.Position = position;
            }
            return count;
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            switch (origin)
            {
                case SeekOrigin.Begin:
                    this.mPosition = offset;
                    return this.mPosition;

                case SeekOrigin.Current:
                    this.mPosition += offset;
                    return this.mPosition;

                case SeekOrigin.End:
                    this.mPosition = this.mLength - offset;
                    return this.mPosition;
            }
            return 0L;
        }

        public override void SetLength(long value)
        {
            throw new NotSupportedException();
        }

        public override string ToString()
        {
            long position = this.Position;
            byte[] buffer = new byte[this.Length];
            this.Read(buffer, 0, (int) this.Length);
            this.Position = position;
            return Encoding.ASCII.GetString(buffer);
        }

        public void Unlock()
        {
            this.mStream.Position = this.mLockPos;
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            throw new NotSupportedException();
        }

        public override bool CanRead
        {
            get
            {
                return true;
            }
        }

        public override bool CanSeek
        {
            get
            {
                return true;
            }
        }

        public override bool CanWrite
        {
            get
            {
                return false;
            }
        }

        public override long Length
        {
            get
            {
                return this.mLength;
            }
        }

        public override long Position
        {
            get
            {
                return this.mPosition;
            }
            set
            {
                this.mPosition = value;
            }
        }

        public long Start
        {
            get
            {
                return this.mStart;
            }
        }
    }
}

